package quoridorDecisionMaker;

import java.util.ArrayList;

import quoridor.Board;
import quoridor.Coordinate;
import quoridor.Move;
import quoridor.QuoridorCoordinate;
import quoridor.QuoridorMove;

public class MoveSearch {
	Board board;
	
	public MoveSearch(Board board) {
		this.board = board;
	}
	
	private void addMove(ArrayList <Move> list, Coordinate tmpCoord, int type) {
		Move move = new QuoridorMove(tmpCoord, 0, board.currentPlayer());
		if (board.validateMove(move)) {
			list.add(move);
		}
	}
	
	private void addValidMove(ArrayList <Move> list, int row, int col) {
		Coordinate tmpCoord = null;
		tmpCoord = new QuoridorCoordinate(row,col);
		if (tmpCoord.isValidCoordinate()) {
			addMove(list, tmpCoord, 0);
		}
		
	}
	
	private void addFencesNearFences(ArrayList <Move> list) {
		boolean [][] fences;
		
		fences = board.getHorizontalFences();
		
		assert(fences != null);
		for (int i = 0; i < fences.length; i++) {
			for (int j = 0; j < fences[i].length; j++) {
				if (fences[i][j]) {
					for (int row = i-1; row <= i + 1; row++) {
						for (int col = j-1; col <= j+1; col++) {
							if (row != i || col != j) {
								addValidFences(list, row, col);
							}
						}
					}	
				}
			}
		}
		fences = board.getVerticalFences();
		assert(fences != null);
		for (int i = 0; i < fences.length; i++) {
			for (int j = 0; j < fences[i].length; j++) {
				if (fences[i][j]) {
					for (int row = i-1; row <= i + 1; row++) {
						for (int col = j-1; col <= j+1; col++) {
							if (row != i || col != j) {
								addValidFences(list, row, col);
							}
						}
					}
				}
			}
		}
	}
	
	private void addFencesNearPlayer(ArrayList <Move> list, Coordinate playerCoord) {
		int row = playerCoord.getRow();
		int col = playerCoord.getColumn();
		
		for (int i = -1; i <= 1; i++) {
			for (int j = -1; j <= 1; j++) {
				if (i != row || j != col) {
					addValidFences(list, row+i, col+j);
				}
			}
		}
		
	}
	
	private void addValidFences(ArrayList <Move> list, int row, int col) {
			Coordinate coord = new QuoridorCoordinate(row, col);
			Move move;
			if (coord.isValidCoordinate()) {
				move = new QuoridorMove(coord, 1, board.currentPlayer());
				if (board.validateMove(move)) {
					list.add(move);
				}
				
				move = new QuoridorMove(coord, 2, board.currentPlayer());
				if (board.validateMove(move)) {
					list.add(move);
				}
			}
	}
	
	public ArrayList <Move> getMoves() {
		Coordinate playerCoord, oppositionCoord;
		playerCoord =  board.getPlayerLocation(board.currentPlayer());
		oppositionCoord = board.getPlayerLocation(board.opposingPlayer());
		ArrayList <Move> list = new ArrayList <Move> ();
		
		//check 4 adjacent squares for valid moves
		addValidMove(list, playerCoord.getRow() + 1, playerCoord.getColumn());
		addValidMove(list, playerCoord.getRow() - 1, playerCoord.getColumn());
		addValidMove(list, playerCoord.getRow(), playerCoord.getColumn() + 1);
		addValidMove(list, playerCoord.getRow(), playerCoord.getColumn() - 1);
		
		//check for valid jumps
		if (playerCoord.isAdjacent(oppositionCoord)) {
			addValidMove(list, oppositionCoord.getRow() + 1, oppositionCoord.getColumn());
			addValidMove(list, oppositionCoord.getRow() - 1, oppositionCoord.getColumn());
			addValidMove(list, oppositionCoord.getRow(), oppositionCoord.getColumn() + 1);
			addValidMove(list, oppositionCoord.getRow(), oppositionCoord.getColumn() - 1);
		}
		
		//search around players for valid fences
		addFencesNearPlayer(list , playerCoord);
		addFencesNearPlayer(list, oppositionCoord);
		
		//search around fences for valid fences to add
		addFencesNearFences(list);
		
		return list;
	}
	
}
